Chapter 9 — Analytical Functions and Grouping
Code Reference File — Copy and paste as needed

========================================
9.1.1 Group by Order Method Type
========================================
grouped = sales.groupby('Order Method Type').agg({
    'Sale Price': 'sum',
    'Quantity Sold': 'sum',
    'Retailer City': 'count'
}).rename(columns={'Retailer City': 'Transaction Count'})
print(grouped)

========================================
9.1.2 Mean Statistics
========================================
mean_qty = sales.groupby('Order Method Type')['Quantity Sold'].mean()
print(mean_qty)

========================================
9.1.3 Multiple Aggregation Functions
========================================
agg_results = sales.groupby('Order Method Type').agg({
    'Sale Price':    ['sum', 'mean', 'max', 'min'],
    'Quantity Sold': ['sum', 'mean', 'max', 'min']
})
print(agg_results)

========================================
9.1.4 Custom Aggregation
========================================
custom_agg = sales.groupby('Order Method Type').agg({
    'Sale Price':    lambda x: x.quantile(0.9),
    'Quantity Sold': 'sum'
})
print(custom_agg)

========================================
9.2 Iterating Over Groups
========================================
for method, group in sales.groupby('Order Method Type'):
    print(f'Order Method: {method}')
    print(group.head(2))

========================================
9.3 Value Counts and Unique Values
========================================
print(sales['Retailer Type'].value_counts())
print(sales['Retailer City'].unique())

========================================
9.4 Filtering Groups
========================================
grouped = sales.groupby('Order Method Type').agg({'Retailer City': 'count'})
filtered = grouped[grouped['Retailer City'] > 50]
print(filtered)

========================================
9.5 Multiple Columns
========================================
multi_group = sales.groupby(['Order Method Type', 'Retailer Type']).agg({
    'Revenue':       'sum',
    'Quantity Sold': 'mean'
})
print(multi_group)

========================================
9.6 Descriptive Statistics
========================================
desc_stats = sales.groupby('Order Method Type')['Sale Price'].describe()
print(desc_stats)

========================================
9.7 Ranking
========================================
sales['Group Rank'] = sales.groupby('Order Method Type')['Sale Price'].rank(method='average', ascending=False)
print(sales[['Order Method Type', 'Sale Price', 'Group Rank']].head())

========================================
9.8 Top N
========================================
top_n = sales.groupby('Order Method Type').apply(lambda x: x.nlargest(3, 'Sale Price'))
print(top_n[['Order Method Type', 'Sale Price']])

========================================
9.9 Conditional Aggregation
========================================
cond_agg = sales[sales['Sale Price'] > 1000].groupby('Order Method Type')['Sale Price'].sum()
print(cond_agg)
